package com.wwu.common.exception;

import com.wwu.common.web.ResultObj;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.io.IOException;
import java.sql.SQLException;

/**
 *  定义全局统一异常处理,目标是消灭95%以上的try-catch代码块，并以优雅的Assert(断言)方式来校验业务的异常
 * 1.Spring在3.2版本增加@RestControllerAdvice和@ControllerAdvice注解
 * 2.注解@RestControllerAdvice是SpringBoot用于捕获@Controller和@RestController层系统抛出的异常
 * (若已编写try-catch且在catch模块中没有使用throw抛出异常,则@RestControllerAdvice捕获不到异常）
 * 3.注解@ExceptionHandler 注解用于指定方法处理的Exception的类型
 * @author 一蓑烟雨
 * @date 2021-11-22 11:01
 * @version 1.0.0
 **/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     *  参数异常
     * @param ex 异常信息
     * @return com.wwu.common.web.ResultObj
     * @author 一蓑烟雨
     * @date 2021/11/22 0022 下午 12:20
     */
    @ExceptionHandler(ParamsException.class)
    public ResultObj paramsExceptionHandler(ParamsException ex){
        log.error("参数异常:",ex);
        return ResultObj.except(ex.getMessage());
    }

    /**
     *  空指针异常
     * @param ex: 异常信息
     * @return com.wwu.common.web.ResultObj
     * @author 一蓑烟雨
     * @date 2021/11/23 0023 上午 11:57
     */
    @ExceptionHandler(NullPointerException.class)
    public ResultObj nullPointerExceptionHandler(NullPointerException ex){
        log.error("空指针异常:",ex);
        return ResultObj.except("空指针异常",ex.getMessage());
    }

    /**
     *   算术异常
     * @param ex: 异常信息
     * @return com.wwu.common.web.ResultObj
     * @author 一蓑烟雨
     * @date 2021/11/23 0023 上午 11:58
     */
    @ExceptionHandler(ArithmeticException.class)
    public ResultObj arithmeticExceptionHandler(ArithmeticException ex){
        log.error("算术异常:",ex);
        return ResultObj.except("算术异常",ex.getMessage());
    }

    /**
     *  类型强制转换异常
     * @param ex: 异常信息
     * @return com.wwu.common.web.ResultObj
     * @author 一蓑烟雨
     * @date 2021/11/23 0023 下午 12:00
     */
    @ExceptionHandler(ClassCastException.class)
    public ResultObj classCastExceptionHandler(ClassCastException ex){
        log.error("类型强制转换异常:",ex);
        return ResultObj.except("类型强制转换异常",ex.getMessage());
    }

    /**
     *  数组下标越界异常
     * @param ex: 异常信息
     * @return com.wwu.common.web.ResultObj
     * @author 一蓑烟雨
     * @date 2021/11/23 0023 下午 12:00
     */
    @ExceptionHandler(ArrayIndexOutOfBoundsException.class)
    public ResultObj arrayIndexOutOfBoundsExceptionHandler(ArrayIndexOutOfBoundsException ex){
        log.error("数组下标越界异常",ex);
        return ResultObj.except("数组下标越界异常",ex.getMessage());
    }

    /**
     *  下标越界异常
     * @param ex: 异常信息
     * @return com.wwu.common.web.ResultObj
     * @author 一蓑烟雨
     * @date 2021/11/23 0023 下午 12:05
     */
    @ExceptionHandler(IndexOutOfBoundsException.class)
    public ResultObj indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex){
        log.error("下标越界异常",ex);
        return ResultObj.except("下标越界异常",ex.getMessage());
    }


    /**
     *  字符串转换为数字异常
     * @param ex: 异常信息
     * @return com.wwu.common.web.ResultObj
     * @author 一蓑烟雨
     * @date 2021/11/23 0023 下午 12:02
     */
    @ExceptionHandler(NumberFormatException.class)
    public ResultObj numberFormatExceptionHandler(NumberFormatException ex){
        log.error("字符串转换为数字异常",ex);
        return ResultObj.except("字符串转换为数字异常",ex.getMessage());
    }

    /**
     *  输入输出异常
     * @param ex: 异常信息
     * @return com.wwu.common.web.ResultObj
     * @author 一蓑烟雨
     * @date 2021/11/23 0023 下午 12:04
     */
    @ExceptionHandler(IOException.class)
    public ResultObj ioExceptionHandler(IOException ex){
        log.error("输入输出异常",ex);
        return ResultObj.except("输入输出异常",ex.getMessage());
    }


    /**
     *  数据库SQL异常
     * @param ex: 异常信息
     * @return com.wwu.common.web.ResultObj
     * @author 一蓑烟雨
     * @date 2021/11/23 0023 上午 11:57
     */
    @ExceptionHandler(SQLException.class)
    public ResultObj sqlExceptionHandler(SQLException ex){
        log.error("执行数据库SQL异常:",ex);
        return ResultObj.except("执行数据库SQL异常",ex.getMessage());
    }
}
